package com.puzzlebazar.client.hashiwokakero;

import com.puzzlebazar.client.hashiwokakero.HashiwokakeroMoveVisitor;
import com.puzzlebazar.client.puzzle.model.MoveClearPuzzle;
import com.puzzlebazar.client.puzzle.model.MoveVisitorImpl;
import com.puzzlebazar.client.squaregrid.view.ImageDrawable;
import com.puzzlebazar.client.squaregrid.view.StringDrawable;
import com.puzzlebazar.client.squaregrid.view.DrawableLayer;
import com.puzzlebazar.client.util.Vec2i;

public class DrawMoveVisitor extends MoveVisitorImpl 
	implements HashiwokakeroMoveVisitor {

	private final DrawableLayer bitmapLayer;
	private final DrawableLayer stringLayer;	
	
	/**
	 * Creates a visitor for drawing the content of the passed moves
	 * 
	 * @param bitmapLayer The layer to draw bitmaps in
	 * @param stringLayer The string layer to draw numbers
	 */
	public DrawMoveVisitor(DrawableLayer bitmapLayer,
			DrawableLayer stringLayer) {
		super();
		this.bitmapLayer = bitmapLayer;
		this.stringLayer = stringLayer;
	}
	
	@Override
	public void visitAddIslandMove(MoveAddIsland move) {
		try{
			Vec2i loc = move.getLoc();
			ImageDrawable circle = new ImageDrawable( loc, null, "circle.png" );
			circle.setBleed(3);			
			bitmapLayer.addDrawable( circle );
			stringLayer.addDrawable( new StringDrawable(
					loc, "gridNumber", null, Integer.toString(move.getValue()) ) );			
		}
		catch( Exception exception ) {
			exception.printStackTrace();
		}
	}

	@Override
	public void visitRemoveIslandMove(MoveRemoveIsland move) {
		try{
			bitmapLayer.removeCellDrawable( move.getLoc(), null );
			stringLayer.removeCellDrawable( move.getLoc(), null );
		}
		catch( Exception exception ) {
			exception.printStackTrace();
		}		
	}

	@Override
	public void visitAddBridgeMove(MoveAddBridge move) {
		try{
			String url;
			Vec2i locFrom = new Vec2i( move.getLoc(0) );
			Vec2i locTo = new Vec2i( move.getLoc(1) );
			int direction = Vec2i.findDirection( locFrom, locTo );
			Vec2i.advanceInDirection(locFrom, direction);
			Vec2i.advanceInDirection(locTo, Vec2i.oppositeDirection(direction) );
			
			switch( direction ) {
			case Vec2i.NORTH:
			case Vec2i.SOUTH:
				url = "vbridge";
				break;
			case Vec2i.EAST:
			case Vec2i.WEST:
				url = "hbridge";
				break;
			default:
				throw new Exception( "Invalid direction" );	
			}
			switch( move.getValue() ) {
			case 1:
				url = url.concat( "1.png" );
				break;
			case 2:
				url = url.concat( "2.png" );
				break;
			default:
				throw new Exception( "Unknown bridge value" );
			}
			
			ImageDrawable drawable = new ImageDrawable( null, url );
			drawable.setCellRectangle(locFrom, locTo);
			bitmapLayer.addDrawable( drawable );
		}
		catch( Exception exception ) {
			exception.printStackTrace();
		}		
	}

	@Override
	public void visitRemoveBridgeMove(MoveRemoveBridge move) {
		try{
			Vec2i locFrom = new Vec2i( move.getLoc(0) );
			Vec2i locTo = new Vec2i( move.getLoc(1) );
			int direction = Vec2i.findDirection( locFrom, locTo );
			Vec2i.advanceInDirection(locFrom, direction);
			Vec2i.advanceInDirection(locTo, Vec2i.oppositeDirection(direction) );			
			
			bitmapLayer.removeCellDrawable( locFrom, locTo, null );
		}
		catch( Exception exception ) {
			exception.printStackTrace();
		}		
	}

	@Override
	public void visitMoveClearPuzzle(MoveClearPuzzle move) throws Exception {
		bitmapLayer.clear();
		stringLayer.clear();	
	}	
	
}
